package gwtappcontainer.server.apis.admin;

import gwtappcontainer.server.apis.admin.Roles.Role;
import gwtappcontainer.server.apps.APIException;
import gwtappcontainer.shared.apis.APIResponse.Status;
import gwtappcontainer.shared.apis.admin.RoleProp;
import gwtappcontainer.shared.apis.admin.UserProp;

import com.google.appengine.api.users.User;

public class GateKeeper {	
	
	public boolean ensureRole(User user, Role... roles) {
		
		String[] roleStrings = new String[roles.length];		
		for (int i = 0; i < roleStrings.length; i++) {
			roleStrings[i] = roles[i].toString();
		}
		
		return ensureRole(user, roleStrings);		
	}
	
	public boolean ensureValidUser(User user) {
		//should be logged in
		if (null == user) 			
			throw new APIException(Status.ERROR_LOGIN_REQUIRED, "User not logged in");
		
		UserProp prop = getUserProp(user);
		
		//should be a valid user
		if (null == prop)
			throw new APIException(Status.ERROR_INVALID_USER, 
					"Invalid user [" + user.getEmail() + "]");		
		
		return true;
	}
	
	public boolean ensureRole(User user, String... roles) {
		
		//should be logged in
		if (null == user) 			
			throw new APIException(Status.ERROR_LOGIN_REQUIRED, "User not logged in");
		
		UserProp prop = getUserProp(user);
		
		//should be a valid user
		if (null == prop)
			throw new APIException(Status.ERROR_INVALID_USER, 
					"Invalid user [" + user.getEmail() + "]");		
																		
		for (String role : roles) {
			if (hasRole(prop, role))
				return true;	
		}
			
		//user does not have any of the specified roles, so throw exception
			
		//construct proper error message
		StringBuilder sb = new StringBuilder();
		for (String role : roles) {			
			sb.append(role + ", ");				
		}			
		String errMessage = "Logged in user [" + prop.email + 
				"] does not have any of the role(s) - [" + sb.toString() + "]";
		
		throw new APIException(Status.ERROR_INSUFFICIENT_PERMISSION, errMessage);		
	}
			
	protected UserProp getUserProp(User user) {								
		UserProp prop = new UserRepository().getUserByEmail(user.getEmail());								
		return prop;
	}
		
	private boolean hasRole(UserProp userProp, String role) {
		if (null == userProp.roles) {
			return false;
		}
		
		role = role.toUpperCase();
		for (RoleProp roleProp : userProp.roles) {
			if (roleProp.name.toUpperCase().equals(role))
				return true;
		}
		
		return false;
	}
}
